package codegen;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

import java.util.*;
import java.util.concurrent.Callable;

@Command(
    name = "generator",
    subcommands = {
        CodeGeneratorCli.Interactive.class,
        CodeGeneratorCli.Batch.class
    },
    description = "Java类生成器"
)
public class CodeGeneratorCli implements Callable<Integer> {
    private static final Scanner scanner = new Scanner(System.in);

    @Override
    public Integer call() {
        while (true) {
            // 先选择要生成的代码类型
            System.out.println("=== 代码生成器 ===\n");
            System.out.println("请选择要生成的代码类型：");
            System.out.println("1. Java实体类");
            System.out.println("2. 比较器类");
            System.out.println("3. JSON转换器");
            System.out.println("4. 退出程序");
            System.out.print("\n请输入选项 (1-4): ");

            String typeChoice = scanner.nextLine().trim();
            if (typeChoice.equals("4")) {
                System.out.println("程序已退出");
                return 0;
            }

            if (!typeChoice.equals("1") && !typeChoice.equals("2") && !typeChoice.equals("3")) {
                System.out.println("无效的选项，请重新选择\n");
                continue;
            }

            // 然后选择生成模式
            System.out.println("\n请选择生成模式：");
            System.out.println("1. 交互式生成（向导模式）");
            System.out.println("2. 批量生成");
            System.out.println("3. 返回上级菜单");
            System.out.print("\n请输入选项 (1-3): ");

            String modeChoice = scanner.nextLine().trim();

            try {
                switch (modeChoice) {
                    case "1":
                        // 传递选择的代码类型
                        new CommandLine(new Interactive()).execute(
                            "-t", typeChoice.equals("1") ? "entity" :
                                 typeChoice.equals("2") ? "comparator" : "json"
                        );
                        break;
                    case "2":
                        // 批量生成模式
                        showBatchInstructions(typeChoice.equals("1"));
                        String cmd = scanner.nextLine().trim();
                        String[] args = parseCommandLine(cmd);
                        return new CommandLine(new Batch()).execute(args);
                    case "3":
                        continue;
                    default:
                        System.out.println("无效的选项，请重新选择\n");
                        continue;
                }

                System.out.print("\n是否继续使用？(y/n): ");
                if (!scanner.nextLine().trim().equalsIgnoreCase("y")) {
                    System.out.println("程序已退出");
                    break;
                }
                System.out.println();

            } catch (Exception e) {
                System.out.println("发生错误: " + e.getMessage());
                return 1;
            }
        }
        return 0;
    }

    private void showBatchInstructions(boolean isEntity) {
        System.out.println("\n批量生成模式");
        System.out.println("命令格式：");
        System.out.println("  -p, --package    包名");
        System.out.println("  -c, --class      类名");
        if (isEntity) {
            System.out.println("  -f, --fields     字段定义（格式：名称:类型）");
            System.out.println("\n示例命令：");
            System.out.println("  -p com.example.model -c User -f id:Long,name:String,age:Integer");
        } else {
            System.out.println("  -f, --fields     字段定义（仅支持int类型，至少2个字段）");
            System.out.println("\n示例命令：");
            System.out.println("  -p com.example.model -c Score -f math:int,english:int,chinese:int");
        }
        System.out.print("\n请输入命令参数: ");
    }

    private String[] parseCommandLine(String cmd) {
        List<String> argsList = new ArrayList<>();
        StringBuilder current = new StringBuilder();
        boolean inQuotes = false;

        for (char c : cmd.toCharArray()) {
            if (c == '"') {
                inQuotes = !inQuotes;
            } else if (c == ' ' && !inQuotes) {
                if (current.length() > 0) {
                    argsList.add(current.toString());
                    current.setLength(0);
                }
            } else {
                current.append(c);
            }
        }

        if (current.length() > 0) {
            argsList.add(current.toString());
        }

        return argsList.toArray(new String[0]);
    }

    @Command(
        name = "interactive",
        description = "交互式生成Java类"
    )
    static class Interactive implements Callable<Integer> {
        @Option(
            names = {"-o", "--output"},
            description = "输出目录",
            defaultValue = "src/main/java"
        )
        private String outputPath;

        @Option(
            names = {"-t", "--type"},
            description = "生成类型 (entity/comparator/json)",
            defaultValue = "entity"
        )
        private String type;

        @Override
        public Integer call() throws Exception {
            Scanner scanner = new Scanner(System.in);
            CodeGenerator generator = new CodeGenerator();

            // 根据type参数生成对应类型
            switch (type) {
                case "entity":
                    generator.generate(1);  // 生成实体类
                    break;
                case "comparator":
                    generator.generate(2);  // 生成比较器类
                    break;
                case "json":
                    generator.generate(3);  // 生成JSON转换器
                    break;
                default:
                    System.out.println("无效的生成类型: " + type);
                    return 1;
            }

            return 0;
        }
    }

    @Command(
        name = "batch",
        description = "批量生成Java类"
    )
    static class Batch implements Callable<Integer> {
        @Option(
            names = {"-p", "--package"},
            description = "包名",
            required = true
        )
        private String packageName;

        @Option(
            names = {"-c", "--class"},
            description = "类名",
            required = true
        )
        private String className;

        @Option(
            names = {"-f", "--fields"},
            description = "字段定义，格式: 名称:类型",
            required = true,
            split = ","
        )
        private String[] fields;

        @Option(
            names = {"-o", "--output"},
            description = "输出目录",
            defaultValue = "src/main/java"
        )
        private String outputPath;

        @Override
        public Integer call() throws Exception {
            List<CodeGenerator.FieldDefinition> fieldDefinitions = new ArrayList<>();
            for (String field : fields) {
                String[] parts = field.split(":");
                if (parts.length == 2) {
                    fieldDefinitions.add(new CodeGenerator.FieldDefinition(
                        parts[0].trim(), parts[1].trim()));
                }
            }

            CodeGenerator generator = new CodeGenerator();

            // 生成实体类
            generator.generateJavaClass(packageName, className, fieldDefinitions, outputPath);
            System.out.println("实体类文件已生成到: " + outputPath + "/" +
                packageName.replace(".", "/") + "/" + className + ".java");

            // 生成比较器类
            generator.generateComparator(packageName, className, fieldDefinitions, outputPath);
            System.out.println("比较器类文件已生成到: " + outputPath + "/" +
                packageName.replace(".", "/") + "/" + className + "Comparator.java");

            // 生成演示类
            generator.generateCompareDemo(packageName, className, fieldDefinitions, outputPath);
            System.out.println("演示类文件已生成到: " + outputPath + "/" +
                packageName.replace(".", "/") + "/" + className + "Demo.java");

            // 生成JSON转换器
            generator.generateJsonConverter(packageName, className, fieldDefinitions, outputPath);
            System.out.println("JSON转换器文件已生成到: " + outputPath + "/" +
                packageName.replace(".", "/") + "/" + className + "JsonConverter.java");

            return 0;
        }
    }
}
